home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / AquaShade / mainblah.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-23  |  8.9 KB  |  286 lines

  1. /*
  2.  
  3. AquaShade hack
  4. MacHack 2001
  5.  
  6. Nicholas Riley
  7. Avi Drissman
  8.  
  9. with thanks to:
  10. Mike Ferris
  11. Chris Nebel
  12. Ed Wynne
  13. Shawn Platkus
  14.  
  15. Known funkiness:
  16. Sometimes, a collapsed window will not get the proper deactivated appearance. No idea why.
  17. Often, the window widget glyphs will stay around after the mouse leaves their proximity. Probably due to the fact that we do window attribute slamming.
  18.  
  19. */
  20.  
  21. #include "main.h"
  22.  
  23. DEFINE_ONE_SHOT_HANDLER_GETTER(MinEventHandler)
  24. DEFINE_ONE_SHOT_HANDLER_GETTER(TicTacEventHandler)
  25. DEFINE_ONE_SHOT_HANDLER_GETTER(CloseEventHandler)
  26.  
  27. void InitAquaShade(void)
  28. {
  29.     static EventLoopTimerUPP eventLoopTimer;
  30.     if (!eventLoopTimer)
  31.         eventLoopTimer = NewEventLoopTimerUPP(EventTimer);
  32.     
  33.     InstallEventLoopTimer(GetMainEventLoop(), kEventDurationSecond, kEventDurationSecond, eventLoopTimer, nil, nil);
  34.     PatchEveryWindow();
  35. }
  36.  
  37. void PatchEveryWindow(void) // Ford every stream...
  38. {
  39.     WindowRef window;
  40.     
  41.     window = GetWindowList();
  42.     while (window)
  43.     {
  44.         PatchWindow(window);
  45.         window = MacGetNextWindow(window);
  46.     }
  47. }
  48.  
  49. void PatchWindow(WindowRef window)
  50. {
  51.     EventTypeSpec minList[] = {{kEventClassWindow, kEventWindowCollapse},
  52.                                 {kEventClassWindow, kEventWindowCollapseAll}};
  53.     EventTypeSpec ttList = {kEventClassWindow, kEventWindowToolbarSwitchMode};
  54.     EventTypeSpec closeList[] = {{kEventClassWindow, kEventWindowClose},
  55.                                   {kEventClassWindow, kEventWindowCloseAll}};
  56.  
  57.     InstallWindowEventHandler(window, GetMinEventHandlerUPP(), 2, minList, nil, nil);
  58.     InstallWindowEventHandler(window, GetTicTacEventHandlerUPP(), 1, &ttList, nil, nil);
  59.     InstallWindowEventHandler(window, GetCloseEventHandlerUPP(), 2, closeList, nil, nil);
  60. }
  61.  
  62. // XXX this is broken
  63. OSStatus pascal CloseEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) {
  64.     WindowRef window;
  65.  
  66.     fprintf(stderr, "I'm closing...\n");
  67.     switch (GetEventKind (inEvent))
  68.     {
  69.         case kEventWindowClose:
  70.             // Get the window
  71.             if (GetEventParameter(inEvent, kEventParamDirectObject, typeWindowRef, nil, sizeof (window), nil, &window))
  72.                 return CallNextEventHandler(inHandlerCallRef, inEvent); //?
  73.             WindowShade(window, false);
  74.             break;
  75.         case kEventWindowCloseAll:
  76.             window = GetWindowList();
  77.             while (window)
  78.             {
  79.                 WindowShade(window, false);
  80.                 window = MacGetNextWindow(window);
  81.             }
  82.     }
  83.     return CallNextEventHandler(inHandlerCallRef, inEvent);
  84. }
  85.  
  86. OSStatus pascal MinEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
  87. {
  88.     WindowRef window;
  89.     
  90.     if (GetCurrentKeyModifiers() & (controlKey | rightControlKeyBit))
  91.         return CallNextEventHandler(inHandlerCallRef, inEvent);
  92.  
  93.     // Get the window
  94.     if (GetEventParameter(inEvent, kEventParamDirectObject, typeWindowRef, nil, sizeof (window), nil, &window))
  95.         return CallNextEventHandler(inHandlerCallRef, inEvent); //?
  96.     
  97.     switch (GetEventKind(inEvent))
  98.     {
  99.         case kEventWindowCollapse:
  100.             WindowShade(window, !(GetCurrentKeyModifiers() & (shiftKey | rightShiftKeyBit)));
  101.             break;
  102.         
  103.         case kEventWindowCollapseAll:
  104.             window = GetWindowList();
  105.             while (window)
  106.             {
  107.                 WindowShade(window, !(GetCurrentKeyModifiers() & (shiftKey | rightShiftKeyBit)));
  108.                 window = MacGetNextWindow(window);
  109.             }
  110.             break;
  111.     }
  112.     
  113.     
  114.     return noErr;
  115. }
  116.  
  117. OSStatus pascal TicTacEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
  118. {
  119.     WindowRef window;
  120.     Boolean collapsed = false;
  121.  
  122.     // Get the window
  123.     GetEventParameter(inEvent, kEventParamDirectObject, typeWindowRef, nil, sizeof (window), nil, &window);
  124.     
  125.     // Is it collapsed?
  126.     GetWindowProperty(window, 'AquaShade ', 'Coll', sizeof(collapsed), nil, &collapsed); // if property isn't there, then we've never touched the window, and it's expanded...
  127.     
  128.     if (collapsed)
  129.         return noErr; // ignore
  130.     else
  131.         return CallNextEventHandler(inHandlerCallRef, inEvent);
  132. }
  133.  
  134. void pascal EventTimer(EventLoopTimerRef inTimer, void *inUserData)
  135. {
  136.     PatchEveryWindow();
  137. }
  138.  
  139. void WindowShade(WindowRef window, Boolean slide)
  140. {
  141.     Boolean collapsed = false;
  142.     struct WindowInfo winfo;
  143.  
  144.     // Should we be expanding or contracting?
  145.     if (GetWindowProperty(window, 'AquaShade ', 'Coll', sizeof(collapsed), nil, &collapsed))
  146.         collapsed = false;
  147.     
  148.     PlaySound();
  149.     
  150.     if (collapsed)
  151.     {
  152.         Rect newRect;
  153.         if (slide)
  154.         {
  155.             GetWindowBounds(window, kWindowGlobalPortRgn, &newRect);
  156.             newRect.top -= kWindowTitleBarHeight;
  157.         }
  158.         
  159.         // we need to restore it
  160.         GetWindowProperty(window, 'AquaShade ', 'Winf', sizeof(winfo), nil, &winfo);
  161.         
  162.         if (slide)
  163.         {
  164.             Point offset;
  165.             offset.h = newRect.left - winfo.oldSize.left;
  166.             offset.v = newRect.top - winfo.oldSize.top;
  167.             winfo.oldSize.top += offset.v;
  168.             winfo.oldSize.bottom += offset.v;
  169.             winfo.oldSize.left += offset.h;
  170.             winfo.oldSize.right += offset.h;
  171.             TransitionWindow(window, kWindowSlideTransitionEffect, kWindowResizeTransitionAction, &winfo.oldSize);
  172.         }
  173.         else
  174.         {
  175.             SizeWindow(window, winfo.oldSize.right - winfo.oldSize.left, winfo.oldSize.bottom - winfo.oldSize.top - kWindowTitleBarHeight, true);
  176.         }
  177.         ChangeWindowAttributes(window, kWindowNoAttributes, 0xFFFFFFFF);
  178.         ChangeWindowAttributes(window, winfo.oldAttrs, kWindowNoAttributes);
  179.         
  180.         collapsed = false;
  181.         SetWindowProperty(window, 'AquaShade ', 'Coll', sizeof(collapsed), &collapsed);
  182.         
  183.         {
  184.             Rect rect = {0x8000, 0x8000, 0x7fff, 0x7fff};
  185.             EventRef eref;
  186.             InvalWindowRect(window, &rect);
  187.             MacCreateEvent(NULL, kEventClassWindow, kEventWindowDrawContent, 0, 0, &eref);
  188.             SetEventParameter(eref, kEventParamDirectObject, typeWindowRef, sizeof(window), &window);
  189.             PostEventToQueue(GetMainEventQueue(), eref, kEventPriorityHigh);
  190.         }
  191.         
  192.         {
  193.             ControlRef root;
  194.             
  195.             GetRootControl(window, &root);
  196.             SetControlVisibility(root, true, true);
  197.         }
  198.     }
  199.     else // must collapse it
  200.     {
  201.         if (slide)
  202.         {
  203.             GetWindowBounds(window, kWindowGlobalPortRgn, &winfo.oldSize);
  204.             winfo.oldSize.top -= kWindowTitleBarHeight;
  205.         }
  206.         else
  207.         {
  208.             GetWindowBounds(window, kWindowContentRgn, &winfo.oldSize);
  209.             winfo.oldSize.bottom += kWindowTitleBarHeight;
  210.         }
  211.         GetWindowAttributes(window, &winfo.oldAttrs);
  212.         SetWindowProperty(window, 'AquaShade ', 'Winf', sizeof(winfo), &winfo);
  213.         
  214.         // take away inconvenient "features"
  215.         ChangeWindowAttributes(window, kWindowNoShadowAttribute, kWindowFullZoomAttribute | kWindowResizableAttribute);
  216.         
  217.         {
  218.             GrafPtr oldPort;
  219.             Rect rect = {0x8000, 0x8000, 0x7fff, 0x7fff};
  220.             Pattern blackPat;
  221.             ControlRef root;
  222.             
  223.             GetRootControl(window, &root);
  224.             SetControlVisibility(root, false, false);
  225.             
  226.             GetPort(&oldPort);
  227.             SetPortWindowPort(window);
  228.             ForeColor(blackColor);
  229.             FillRect(&rect, GetQDGlobalsBlack(&blackPat));
  230.             SetPort(oldPort);
  231.         }
  232.  
  233.         // collapse
  234.         if (slide)
  235.         {
  236.             winfo.oldSize.bottom = winfo.oldSize.top + kWindowTitleBarHeight + 1;
  237.             TransitionWindow(window, kWindowSlideTransitionEffect, kWindowResizeTransitionAction, &winfo.oldSize);
  238.         }
  239.         else
  240.         {
  241.             SizeWindow(window, winfo.oldSize.right - winfo.oldSize.left, 1, true);
  242.         }
  243.         
  244.         collapsed = true;
  245.         SetWindowProperty(window, 'AquaShade ', 'Coll', sizeof(collapsed), &collapsed);
  246.     }
  247. }
  248.  
  249. void PlaySound() {
  250.     SysBeep(100);
  251.     /*
  252.     FSRef fref;
  253.     OSErr err = FSPathMakeRef("/Users/avidriss/AquaShade/open", &fref, NULL);
  254.     Movie movie;
  255.     FSSpec fsp;
  256.     short refnum;
  257.     
  258.     if (err != noErr) ExitToShell();
  259.  
  260.     err = FSGetCatalogInfo(&fref, 0, NULL, NULL, &fsp, NULL);
  261.     if (err != noErr) ExitToShell();
  262.     /*
  263.     OpenMovieFile(&fsp, &refnum, fsRdPerm);
  264.     NewMovieFromFile(&movie, refnum, NULL, (StringPtr)NULL, newMovieActive, NULL);
  265.     if (refnum != 0)
  266.         CloseMovieFile(refnum);
  267.             
  268.     // play the movie once thru
  269.     StartMovie(movie);
  270.     while (!IsMovieDone(movie))
  271.         MoviesTask(movie, 0);
  272.     DisposeMovie(movie);
  273.     
  274.     
  275.     err = FSpOpenDF( &fsp, fsRdPerm, 
  276.                                   &refnum );
  277.     if ( err != noErr )
  278.       ExitToShell();
  279.  
  280.     err = SndStartFilePlay( nil, refnum, 0, 40960, nil, nil, nil, false );
  281.     if ( err != noErr )
  282.       ExitToShell();
  283.     */
  284.  }
  285.  
  286.